use chrono::Utc;
use hmac::{Hmac, Mac};
use sha2::{Digest, Sha256};
use serde::{Deserialize, Serialize};
use std::error::Error;

// 定义API请求体结构
#[derive(Serialize)]
struct TranslationRequest<'a> {
    #[serde(rename = "SourceLanguage")]
    source_language: &'a str,
    #[serde(rename = "TargetLanguage")]
    target_language: &'a str,
    #[serde(rename = "TextList")]
    text_list: Vec<&'a str>,
}

// 定义API响应结构
#[derive(Deserialize, Debug, Serialize)]
pub struct TranslationResponse {
    #[serde(rename = "TranslationList")]
    pub translation_list: Option<Vec<TranslationItem>>,
    #[serde(rename = "ResponseMetadata")]
    pub response_metadata: ResponseMetadata,
}

#[derive(Deserialize, Debug, Serialize)]
pub struct TranslationItem {
    #[serde(rename = "Translation")]
    pub translation: String,
}

#[derive(Deserialize, Debug, Serialize)]
pub struct ResponseMetadata {
    #[serde(rename = "RequestId")]
    pub request_id: String,
    #[serde(rename = "Action")]
    pub action: String,
    #[serde(rename = "Version")]
    pub version: String,
    #[serde(rename = "Service")]
    pub service: String,
    #[serde(rename = "Region")]
    pub region: String,
    #[serde(rename = "Error")]
    pub error: Option<ResponseError>,
}

#[derive(Deserialize, Debug, Serialize)]
pub struct ResponseError {
    #[serde(rename = "Code")]
    pub code: String,
    #[serde(rename = "Message")]
    pub message: String,
}

// 创建 HMAC-SHA256 签名
fn create_signature(
    secret_key: &str,
    date: &str,
    region: &str,
    service: &str,
    string_to_sign: &str,
) -> String {
    type HmacSha256 = Hmac<Sha256>;

    let mut mac1 = HmacSha256::new_from_slice(secret_key.as_bytes()).unwrap();
    mac1.update(date.as_bytes());
    let k_date = mac1.finalize().into_bytes();

    let mut mac2 = HmacSha256::new_from_slice(&k_date).unwrap();
    mac2.update(region.as_bytes());
    let k_region = mac2.finalize().into_bytes();

    let mut mac3 = HmacSha256::new_from_slice(&k_region).unwrap();
    mac3.update(service.as_bytes());
    let k_service = mac3.finalize().into_bytes();

    let mut mac4 = HmacSha256::new_from_slice(&k_service).unwrap();
    mac4.update(b"request");
    let k_signing = mac4.finalize().into_bytes();

    let mut mac = HmacSha256::new_from_slice(&k_signing).unwrap();
    mac.update(string_to_sign.as_bytes());
    
    hex::encode(mac.finalize().into_bytes())
}

// 公开的翻译函数
pub async fn translate(
    access_key: &str,
    secret_key: &str,
    text: &str,
    source_lang: &str,
    target_lang: &str,
) -> Result<TranslationResponse, Box<dyn Error>> {
    let client = reqwest::Client::new();
    let now = Utc::now();
    let x_date = now.format("%Y%m%dT%H%M%SZ").to_string();
    let date = now.format("%Y%m%d").to_string();

    let request_body = TranslationRequest {
        source_language: source_lang,
        target_language: target_lang,
        text_list: vec![text],
    };
    let body_str = serde_json::to_string(&request_body)?;
    let hashed_payload = hex::encode(sha2::Sha256::digest(body_str.as_bytes()));

    let service = "translate";
    let region = "cn-north-1";
    let action = "TranslateText";
    let version = "2020-06-01";

    let canonical_query = format!("Action={}&Version={}", action, version);

    // 构造规范请求
    let canonical_request = format!(
        "POST\n/\n{}\ncontent-type:application/json; charset=utf-8\nhost:open.volcengineapi.com\nx-date:{}\n\ncontent-type;host;x-date\n{}",
        canonical_query,
        x_date,
        hashed_payload
    );
    
    let hashed_canonical_request = hex::encode(sha2::Sha256::digest(canonical_request.as_bytes()));

    // 构造待签名字符串
    let credential_scope = format!("{}/{}/{}/request", date, region, service);
    let string_to_sign = format!(
        "HMAC-SHA256\n{}\n{}\n{}",
        x_date,
        credential_scope,
        hashed_canonical_request
    );

    // 计算签名
    let signature = create_signature(secret_key, &date, region, service, &string_to_sign);

    // 构造 Authorization 头部
    let authorization = format!(
        "HMAC-SHA256 Credential={}/{}, SignedHeaders=content-type;host;x-date, Signature={}",
        access_key, credential_scope, signature
    );

    let url = format!("https://open.volcengineapi.com/?Action={}&Version={}", action, version);

    // 发送请求
    let resp = client
        .post(&url)
        .header("Content-Type", "application/json; charset=utf-8")
        .header("Host", "open.volcengineapi.com")
        .header("X-Date", &x_date)
        .header("Authorization", authorization)
        .body(body_str)
        .send()
        .await?
        .json::<TranslationResponse>()
        .await?;

    Ok(resp)
}